package com.base.commonlib.utils;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.widget.Toast;

import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.Iterator;
import java.util.Set;
import java.util.UUID;

/**
 * Created by arvin on 2018/5/25.
 */

public class PrintUtil {

    private static Handler handler;
    private static OutputStreamWriter writer;

    public static final int NORMAL = 0; //正常打印
    public static final int BOLD = 1; //加粗打印
    public static final int HIGHERX01 = 16; //高X1
    public static final int HIGHERX2 = 2; //高X2
    public static final int HIGHERX3 = 3; //高X3
    public static final int HIGHERX4 = 4; //高X4
    public static final int HIGHERX5 = 5; //高X5
    public static final int ALIGNLEFT = 6; //居左
    public static final int ALIGNMIDDLE = 7; //居中
    public static final int ALIGNRIGHT = 8; //居右
    public static final int UNDERLINE = 9; //下划线

    public static final int SCALEX2 = 10; //放大X2
    public static final int SCALEX3 = 11; //放大X3
    public static final int SCALEX4 = 12; //放大X4
    public static final int SCALEX5 = 13; //放大X5

    public static final int THATOK = 14;//行间距
    private static BluetoothSocket bluetoothSocket;


    public static void init(Context context, final PrintRunnable run) {

        if (handler != null) {
            return;
        }
        HandlerThread printThread = new HandlerThread("print");
        printThread.start();
        handler = new Handler(printThread.getLooper());
        final Handler mainHandler = new Handler(Looper.getMainLooper());

        final PbDialog pd = new PbDialog(context);
        pd.setCancelable(false);
        BluetoothAdapter defaultAdapter = BluetoothAdapter.getDefaultAdapter();

        if (defaultAdapter == null) {
            Toast.makeText(context, "不支持蓝牙！", Toast.LENGTH_SHORT).show();
            PrintUtil.handler.getLooper().quit();
            return;
        }
        if (!defaultAdapter.enable()) {
            Toast.makeText(context, "蓝牙未打开！", Toast.LENGTH_SHORT).show();
            endAndRelease();
        } else {
            Set<BluetoothDevice> devices = defaultAdapter.getBondedDevices();
            final Iterator<BluetoothDevice> iterator = devices.iterator();
            if (!iterator.hasNext()) {
                Toast.makeText(context, "蓝牙未连接！", Toast.LENGTH_SHORT).show();
                endAndRelease();
            } else {

                PrintUtil.handler.post(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            mainHandler.post(new Runnable() {
                                @Override
                                public void run() {
                                    pd.show();
                                }
                            });

                            while (iterator.hasNext()) {
                                BluetoothDevice device = iterator.next();
                                bluetoothSocket = device.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
                                if (!bluetoothSocket.isConnected()) {
                                    try {
                                        bluetoothSocket.connect();
                                    } catch (Exception E) {
                                        continue;
                                    }
                                }
                                OutputStream outputStream = bluetoothSocket.getOutputStream();
                                writer = new OutputStreamWriter(outputStream, "GBK");
                                printStart();
                                run.run();
                                break;
                            }


                        } catch (Exception e) {
                            e.printStackTrace();
                            ToastUtil.show("请检查打印机是否正确连接");
                        } finally {
                            endAndRelease();
                            mainHandler.post(new Runnable() {
                                @Override
                                public void run() {
                                    pd.dismiss();
                                }
                            });

                        }
                    }
                });


            }
        }
    }

    private static void printStart() throws Exception {
        try {
            writer.write(0x1B);
            writer.write(0x40);
            writer.flush();
        } catch (Exception e) {
            throw e;
        }
    }


    public static void printText(String str, int[] types) throws Exception {
        try {
            loadStyle(types);
            writer.write(str);
            writer.flush();
        } catch (Exception e) {
            throw e;

        }
    }


    public static void endAndRelease() {
        try {
            writer.flush();
            writer.close();
            writer = null;
            bluetoothSocket.close();


        } catch (Exception e) {
            try {
                bluetoothSocket.close();
                bluetoothSocket = null;
            } catch (Exception t) {

            }

        } finally {
            handler.getLooper().quit();
            handler = null;
        }
    }


    public static void printToBlackMark() throws Exception {
        try {
            writer.write(0x0c);
            writer.flush();
        } catch (Exception e) {
            throw e;
        }

    }


    //此方法使用十进制指令，便于设定行数
    public static void printLines(int lines) throws Exception {
        try {
            writer.write(27);
            writer.write(100);
            writer.write(lines);
            writer.flush();
        } catch (Exception e) {
            throw e;
        }
    }


    private static void loadStyle(int[] types) throws Exception {
        try {
            //恢复所有默认格式
            writer.write(0x1b);
            writer.write(0x45);
            writer.write(0x00);

            writer.write(0x1d);
            writer.write(0x21);
            writer.write(0x00);

            writer.write(0x1b);
            writer.write(0x61);
            writer.write(0x00);

            writer.write(0x1c);
            writer.write(0x2d);
            writer.write(0x00);

            writer.write(0x1b);
            writer.write(0x2d);
            writer.write(0x00);

//            writer.write(0x1b);
//            writer.write(0x33);
//            writer.write(0x21);
            //设置行间距


            if (types != null && types.length > 0) {
                for (int i = 0; i < types.length; i++)
                    switch (types[i]) {
                        case NORMAL:

                            break;
                        case BOLD:
                            writer.write(0x1b);
                            writer.write(0x45);
                            writer.write(0x01);
                            break;
                        case HIGHERX01:
                            writer.write(0x1d);
                            writer.write(0x21);
                            writer.write(0x00);
                            break;
                        case HIGHERX2:
                            writer.write(0x1d);
                            writer.write(0x21);
                            writer.write(0x01);
                            break;
                        case HIGHERX3:
                            writer.write(0x1d);
                            writer.write(0x21);
                            writer.write(0x02);
                            break;
                        case HIGHERX4:
                            writer.write(0x1d);
                            writer.write(0x21);
                            writer.write(0x03);
                            break;
                        case HIGHERX5:
                            writer.write(0x1d);
                            writer.write(0x21);
                            writer.write(0x04);
                            break;
                        case ALIGNLEFT:
                            writer.write(0x1b);
                            writer.write(0x61);
                            writer.write(0x00);
                            break;
                        case ALIGNMIDDLE:
                            writer.write(0x1b);
                            writer.write(0x61);
                            writer.write(0x01);
                            break;
                        case ALIGNRIGHT:
                            writer.write(0x1b);
                            writer.write(0x61);
                            writer.write(0x02);
                            break;
                        case UNDERLINE:
                            writer.write(0x1c);
                            writer.write(0x2d);
                            writer.write(0x02);//西文下划线

                            writer.write(0x1b);
                            writer.write(0x2d);
                            writer.write(0x02);//中文下划线
                            break;
                        case SCALEX2:
                            writer.write(0x1d);
                            writer.write(0x21);
                            writer.write(0x11);
                            break;
                        case SCALEX3:
                            writer.write(0x1d);
                            writer.write(0x21);
                            writer.write(0x22);
                            break;
                        case SCALEX4:
                            writer.write(0x1d);
                            writer.write(0x21);
                            writer.write(0x33);
                            break;
                        case SCALEX5:
                            writer.write(0x1d);
                            writer.write(0x21);
                            writer.write(0x44);
                            break;
                        case THATOK:
                            writer.write(0x1d);
                            writer.write(0x21);
                            writer.write(0X5a);
                            break;
                    }
            }
        } catch (Exception e) {
            throw e;
        }
    }

    public interface PrintRunnable {
        void run() throws Exception;
    }


}
